package fina2.dcs.fis;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import javax.ejb.EJB;
import javax.ejb.Remove;
import javax.ejb.Stateful;

import org.jboss.annotation.ejb.LocalBinding;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.Destroy;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.log.Log;

import fina2.dcs.i18n.LanguageSession;
import fina2.dcs.security.User;
import fina2.dcs.security.UserLocal;
import fina2.dcs.system.SysString;
import fina2.dcs.system.SysStringLocal;
import fina2.dcs.system.SysStringPk;
import fina2.dcs.system.SysUserBankLocal;

@Stateful
@Name("fiListSession")
@Scope(ScopeType.SESSION)
@LocalBinding(jndiBinding = "FiListSession/local")
@AutoCreate
public class FiListSession implements FiListLocal,Serializable {
	
	@Logger
	private Log log;

	private Bank bank = new Bank();

	private Bank selectedBank = new Bank();

	private Bank bankToRemove = new Bank();

	private List<BankType> fiListData = new ArrayList<BankType>();

	private List<Bank> banks = new ArrayList<Bank>();

	@EJB(beanInterface = SysStringLocal.class)
	private SysStringLocal sysStringLocal;

	@EJB(beanInterface = BankGroupLocal.class)
	private BankGroupLocal bankGroupLocal;

	@EJB(beanInterface = LicenceLocal.class)
	private LicenceLocal licLocal;

	@EJB(beanInterface = LicenceTypeLocal.class)
	private LicenceTypeLocal licTypeLocal;

	@EJB(beanInterface = MMBankGroupLocal.class)
	private MMBankGroupLocal mmBGroupLocal;

	@EJB(beanInterface = BankLocal.class)
	private BankLocal bankLocal;

	@EJB(beanInterface = SysUserBankLocal.class)
	private SysUserBankLocal userBankLocal;

	@EJB(beanInterface = UserLocal.class)
	private UserLocal ul;

	@EJB(beanInterface = BankBranchLocal.class)
	private BankBranchLocal bankBranchLocal;

	@EJB(beanInterface = BankTypeLocal.class)
	private BankTypeLocal btLocal;

	@EJB(beanInterface = BankManagementLocal.class)
	private BankManagementLocal bankManLocal;

	private final BigDecimal defaultIndex = new BigDecimal("1.0");

	private boolean bankAdded = false;

	private boolean initFirst = false;

	
	
	public void init() {
		if (!initFirst) {
			log.info("Initializing Fi List");

			try {

				User u = ul.getCurrentUser();
				if (u.getLogin().toLowerCase().trim().equals("sa") || u.getLogin().toLowerCase().trim().equals("admin")) {
					banks = bankLocal.getAllBanks();
				} else {
					banks = userBankLocal.getAllUsersBanks(u.getId());
					List<BigDecimal> ids = new ArrayList<BigDecimal>();
					for (int i = 0; i < banks.size(); i++) {
						ids.add(banks.get(i).getNamestrid());
					}

					StringBuffer sb = new StringBuffer(ids.toString());

					sb.replace(0, 1, "");
					sb.replace(sb.length() - 1, sb.length(), "");
					List<SysString> names = sysStringLocal.getAllValues(sb.toString(), LanguageSession.langId);
					for (int i = 0; i < banks.size(); i++)
						for (int j = 0; j < names.size(); j++) {
							if (banks.get(i).getNamestrid().equals(names.get(j).getPk().getId())) {
								banks.get(i).setName(names.get(j).getValue());
								break;
							}
						}

					for (int i = 0; i < banks.size(); i++) {
						banks.get(i).setBankType(bankLocal.getBankTypeByTypeId(banks.get(i).getTypeId()));
					}
				}
				log.info("Fi List Initialized");
				initFirst = true;

			} catch (Exception ex) {
				log.error(ex.getMessage(), ex);
			}
		}

	}

	public Bank getBankToRemove() {
		return bankToRemove;
	}

	public void setBankToRemove(Bank bankToRemove) {
		this.bankToRemove = bankToRemove;
	}

	public void removeFi() {
		log.info("Trying To Remove Bank");
		try {
			bankLocal.removeBank(bankToRemove);
			banks.remove(bankToRemove);
			log.info("Bank Removed");
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
		}
	}

	public List<Bank> getBanks() {
		return banks;
	}

	public void setBanks(List<Bank> banks) {
		this.banks = banks;
	}

	public void initSubTree(String code) {
		bank.setCode(code);
		if (fiListData != null) {
			for (int i = 0; i < fiListData.size(); i++) {
				if (!fiListData.get(i).getBanks().contains(bank)) {
					fiListData.remove(i);
					i--;
				}
			}
			List<Bank> banks = fiListData.get(0).getBanks();
			for (int i = 0; i < banks.size(); i++) {
				if (!banks.get(i).getCode().trim().equals(bank.getCode().trim())) {
					banks.remove(i);
					i--;
				}
			}

		}

	}

	public void addBank(String selectedGroup,String code,String shortName,String swiftCode,String name,String address,String phone,String fax,String email, String selectedFiType) { 
		log.info("**********Trying to add bank**********");
		bankAdded = false;
		try {
			BigDecimal maxSysStringId = sysStringLocal.getMaxId();

			bank.setId(bankLocal.getMaxId().add(defaultIndex));

			bank.setAddressStrId(maxSysStringId.add(defaultIndex));
			SysStringPk ssAddressPk = new SysStringPk(bank.getAddressStrId(), LanguageSession.langId);
			SysString ssAddress = new SysString();
			ssAddress.setPk(ssAddressPk);
			ssAddress.setValue(address);
			sysStringLocal.addString(ssAddress);

			bank.setNamestrid(bank.getAddressStrId().add(defaultIndex));
			SysStringPk ssNamePk = new SysStringPk(bank.getNamestrid(), LanguageSession.langId);
			SysString ssName = new SysString();
			ssName.setPk(ssNamePk);
			ssName.setValue(name);
			sysStringLocal.addString(ssName);

			bank.setShortNameStrId(bank.getNamestrid().add(defaultIndex));
			SysStringPk ssShortNamePk = new SysStringPk(bank.getShortNameStrId(), LanguageSession.langId);
			SysString ssShortName = new SysString();
			ssShortName.setPk(ssShortNamePk);
			ssShortName.setValue(shortName);
			sysStringLocal.addString(ssShortName);

			StringTokenizer stFi = new StringTokenizer(selectedFiType, "/");
			BankType bt = btLocal.findByCode(stFi.nextToken());
			bank.setTypeId(bt.getId());
			StringTokenizer stG = new StringTokenizer(selectedGroup, "/");
			BankGroup bg = bankGroupLocal.findByCode(stG.nextToken());
			MMBankGroupPk pk = new MMBankGroupPk(bank.getId().floatValue(), bg.getId().floatValue());
			MMBankGroup mmBG = new MMBankGroup(pk);

			mmBGroupLocal.addMMBankGroup(mmBG);
			bankLocal.addBank(bank);
			banks.add(bank);
			bank = new Bank();
			log.info("**********Bank Added**********");
			bankAdded = true;
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
		}
	}

	public void addLicense() {

	}

	public List<BankType> getFiListData() {
		return fiListData;
	}

	public void setFiListData(List<BankType> fiListData) {
		this.fiListData = fiListData;
	}

	public Bank getBank() {
		return bank;
	}

	public void setBank(Bank bank) {
		this.bank = bank;
	}

	public boolean isBankAdded() {
		return bankAdded;
	}

	public void setBankAdded(boolean bankAdded) {
		this.bankAdded = bankAdded;
	}

	public Bank getSelectedBank() {
		return selectedBank;
	}

	public void setSelectedBank(Bank selectedBank) {
		SysString sName = sysStringLocal.findByPk(new SysStringPk(selectedBank.getShortNameStrId(), LanguageSession.langId));
		String shortName = (sName != null) ? sName.getValue() : null;
		SysString addressString = sysStringLocal.findByPk(new SysStringPk(selectedBank.getAddressStrId(), LanguageSession.langId));
		String address = (addressString != null) ? addressString.getValue() : null;
		selectedBank.setShortName(shortName);
		selectedBank.setAddress(address);
		List<Licence> lics = licLocal.findByBankId(selectedBank.getId());
		List<LicenceType> licTypes = new ArrayList<LicenceType>();
		for (int i = 0; i < lics.size(); i++) {
			licTypes.add(licTypeLocal.findById(lics.get(i).getTypeId()));
		}
		List<BankBranch> bankBrs = bankBranchLocal.loadBranchesByBankId(selectedBank.getId());
		List<BankManagement> bankMan = bankManLocal.loadManagementByBankId(selectedBank.getId());
		selectedBank.setLicenceTypes(licTypes);
		selectedBank.setBankBranches(bankBrs);
		selectedBank.setBankMan(bankMan);
		this.selectedBank = selectedBank;
	}

	@Remove
	@Destroy
	public void remove() {

	}
}
